﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CEntityMgr:MonoBehaviour
{
	public bool debug = false;
	public static CEntityMgr Ins { get; private set; }

	private Dictionary<int, CEntity> entitys = new Dictionary<int, CEntity>();
	private Dictionary<int,HashSet<int>> handled = new Dictionary<int, HashSet<int>>();
	private List<HashSet<int>> pool = new List<HashSet<int>>();
	private void Awake()
	{
		Ins = this;
	}
	public void Add(CEntity entity)
	{
		entitys.Add(entity.entityId, entity);
	}
	public void Remove(CEntity entity)
	{
		entitys.Remove(entity.entityId);
	}
    
    void Update()
    {
		foreach(var v in handled)
		{
			pool.Add(v.Value);
		}
		handled.Clear();
		foreach (var v in entitys)
		{
			CheckColliders(v.Value);
		}
		foreach(var v in entitys)
		{
			v.Value.Tick();
		}
    }
	private void CheckColliders(CEntity entity)
	{
		foreach (var v in entitys)
		{
			var e = v.Value;
			if (e == entity) continue;
			if (handled.TryGetValue(entity.entityId,out var list))
			{
				if(list.Contains(e.entityId))
					continue;
			}
			
			var dir = e.transform.position - entity.transform.position;
			if(Mathf.Approximately(dir.x,0)&& Mathf.Approximately(dir.z, 0))
			{
				dir.x = 0.0001f;
			}
			dir.y = 0;
			bool flag = dir.sqrMagnitude < Mathf.Pow(entity.bodyRadius + e.bodyRadius, 2);
			if (flag)
			{
				float dis = entity.bodyRadius + e.bodyRadius - dir.magnitude;
				dir = dir.normalized;
				e.AddForce(dir * dis / 2);
				entity.AddForce(-dir * dis / 2);
				if(handled.TryGetValue(e.entityId,out var value))
				{
					value.Add(entity.entityId);
				}
				else
				{
					HashSet<int> set = null;
					if(pool.Count == 0)
						set = new HashSet<int>();
					else
					{
						set = pool[pool.Count - 1];
						pool.RemoveAt(pool.Count - 1);
					}
					set.Add(entity.entityId);
					handled.Add(e.entityId, set);
				}
			}
		}
	}
	private void OnDestroy()
	{
		Ins = null;
	}
}
